﻿using OSGeo.GDAL;
using OSGeo.OGR;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp
{
    public class Gdal2TilesWrapper
    {
        public static void generateTiles(string tifPath, string outputPath, int minZoom, int maxZoom, string pyPath)
        {

        }

        public static void LMain()
        {
            // 初始化 GDAL
            GdalConfiguration.ConfigureGdal();
            GdalConfiguration.ConfigureOgr();
            OSGeo.GDAL.Gdal.AllRegister();
            OSGeo.OGR.Ogr.RegisterAll();

            string inputGeoTiff = @"D:\data\PowerStations\武川测试\WorkProjects\武川测试_光伏巡检_第1次作业\红外武川_T.tif";
            string outputDirectory = @"D:\data\PowerStations\武川测试\WorkProjects\武川测试_光伏巡检_第1次作业\tiffsplits";
            int tileSize = 512;
            int zoomLevel = 20;
            int tileX = 869472;
            int tileY = 613656;

            // 生成瓦片
            //GenerateTiles(inputGeoTiff, outputDirectory, tileSize);

            // 计算瓦片坐标信息
            CalculateTileCoordinates(outputDirectory, zoomLevel, tileX, tileY, tileSize);

            Console.WriteLine("处理完成!");
        }

        // 调用 gdal2tiles.py 生成瓦片
        static void GenerateTiles(string inputPath, string outputPath, int tileSize)
        {
            string gdal2tilesPath = FindGdal2TilesPath();

            if (string.IsNullOrEmpty(gdal2tilesPath))
            {
                Console.WriteLine("未找到 gdal2tiles.py，请确保已安装 GDAL");
                return;
            }

            string arguments = $"-z 20-20 --xyz --processes=4 --tilesize={tileSize} \"{inputPath}\" \"{outputPath}\"";

            ProcessStartInfo startInfo = new ProcessStartInfo
            {
                FileName = "python",
                Arguments = $"\"{gdal2tilesPath}\" {arguments}",
                UseShellExecute = false,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                CreateNoWindow = true
            };

            using (Process process = new Process())
            {
                process.StartInfo = startInfo;
                process.OutputDataReceived += (sender, args) => Console.WriteLine(args.Data);
                process.ErrorDataReceived += (sender, args) => Console.WriteLine($"错误: {args.Data}");

                Console.WriteLine($"正在生成瓦片: {arguments}");
                process.Start();
                process.BeginOutputReadLine();
                process.BeginErrorReadLine();
                process.WaitForExit();

                if (process.ExitCode != 0)
                {
                    Console.WriteLine("瓦片生成过程可能出错");
                }
            }
        }

        // 查找 gdal2tiles.py 路径
        static string FindGdal2TilesPath()
        {
            string[] possiblePaths = {
                "/usr/bin/gdal2tiles.py", // Linux
                "/usr/local/bin/gdal2tiles.py", // macOS
                "C:\\OSGeo4W\\bin\\gdal2tiles.py", // Windows OSGeo4W
                "C:\\Program Files\\GDAL\\gdal2tiles.py" // Windows
            };

            foreach (string path in possiblePaths)
            {
                if (File.Exists(path))
                {
                    return path;
                }
            }

            // 尝试通过 which/where 命令查找
            try
            {
                ProcessStartInfo startInfo = new ProcessStartInfo
                {
                    FileName = Environment.OSVersion.Platform == PlatformID.Win32NT ? "where" : "which",
                    Arguments = "gdal2tiles.py",
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    CreateNoWindow = true
                };

                using (Process process = Process.Start(startInfo))
                {
                    string result = process.StandardOutput.ReadToEnd().Trim();
                    if (!string.IsNullOrEmpty(result) && File.Exists(result))
                    {
                        return result;
                    }
                }
            }
            catch
            {
                // 忽略异常
            }

            return null;
        }

        // 计算瓦片坐标信息
        static void CalculateTileCoordinates(string tilesPath, int z, int x, int y, int tileSize)
        {
            string tilePath = Path.Combine(tilesPath, z.ToString(), x.ToString(), $"{y}.png");

            if (!File.Exists(tilePath))
            {
                Console.WriteLine($"瓦片文件不存在: {tilePath}");
                //return;
            }

            // 获取原始 GeoTIFF 文件以获取地理参考信息
            // 这里假设我们知道原始文件路径，实际应用中可能需要存储这些信息
            string originalGeoTiff = @"D:\data\PowerStations\武川测试\WorkProjects\武川测试_光伏巡检_第1次作业\红外武川_T.tif";

            using (Dataset dataset = Gdal.Open(originalGeoTiff, Access.GA_ReadOnly))
            {
                if (dataset == null)
                {
                    Console.WriteLine("无法打开原始 GeoTIFF 文件");
                    return;
                }

                double[] geoTransform = new double[6];
                dataset.GetGeoTransform(geoTransform);

                // 计算此瓦片对应的地理范围
                (double minLon, double maxLon, double minLat, double maxLat) =
                    CalculateTileBounds(z, x, y, tileSize, geoTransform, dataset.RasterXSize, dataset.RasterYSize);

                Console.WriteLine($"瓦片 {z}/{x}/{y}.png 的地理范围:");
                Console.WriteLine($"左上角: ({minLon}, {maxLat})");
                Console.WriteLine($"右上角: ({maxLon}, {maxLat})");
                Console.WriteLine($"右下角: ({maxLon}, {minLat})");
                Console.WriteLine($"左下角: ({minLon}, {minLat})");
                Console.WriteLine($"中心点: ({(minLon + maxLon) / 2}, {(minLat + maxLat) / 2})");

                // 计算瓦片内任意像素点(例如中心点)的坐标
                int pixelX = tileSize / 2;
                int pixelY = tileSize / 2;

                (double pixelLon, double pixelLat) = PixelToWorld(
                    x * tileSize + pixelX,
                    y * tileSize + pixelY,
                    geoTransform);

                Console.WriteLine($"像素点({pixelX},{pixelY})的坐标: ({pixelLon}, {pixelLat})");
            }
        }

        // 计算瓦片的地理边界
        static (double minLon, double maxLon, double minLat, double maxLat) CalculateTileBounds(
            int z, int x, int y, int tileSize, double[] geoTransform, int rasterXSize, int rasterYSize)
        {
            // 计算瓦片在原始图像中的像素范围
            int pixelX = x * tileSize;
            int pixelY = y * tileSize;

            // 将像素坐标转换为地理坐标
            (double ulLon, double ulLat) = PixelToWorld(pixelX, pixelY, geoTransform);
            (double lrLon, double lrLat) = PixelToWorld(pixelX + tileSize, pixelY + tileSize, geoTransform);

            return (
                Math.Min(ulLon, lrLon),
                Math.Max(ulLon, lrLon),
                Math.Min(ulLat, lrLat),
                Math.Max(ulLat, lrLat)
            );
        }

        // 像素坐标转地理坐标
        static (double lon, double lat) PixelToWorld(int pixelX, int pixelY, double[] geoTransform)
        {
            double x = geoTransform[0] + pixelX * geoTransform[1] + pixelY * geoTransform[2];
            double y = geoTransform[3] + pixelX * geoTransform[4] + pixelY * geoTransform[5];
            return (x, y);
        }

    }
}
